package service

import (
	"context"
	"encoding/json"
	"errors"
	"math/rand"
	"sync"
	"time"
	__ "user_srv/basic/userproto"
	"user_srv/handler/dao"
	"user_srv/handler/models"
	"user_srv/untils"
)

type Server struct {
	__.UnimplementedUserServer
}

// 实名认证
func (s *Server) RealName(_ context.Context, in *__.RealNameReq) (*__.RealNameResp, error) {
	res, reason := untils.RealUser(in.IdCard, in.RealName)
	if res == false {
		return nil, errors.New("实名认证失败:" + reason)
	}
	var u models.User
	u.Id = in.Id
	u.IdCard = in.IdCard
	u.RealName = in.RealName
	u.IdCardVerificationStatus = 2
	if err := u.Updates(); err != nil {
		return nil, errors.New("信息保存失败：" + err.Error())
	}
	return &__.RealNameResp{Id: in.Id}, nil
}

// 用户详情
func (s *Server) UserDetail(_ context.Context, in *__.UserDetailReq) (*__.UserDetailResp, error) {
	u, err := dao.GetUserById(in.Id)
	if err != nil {
		return nil, err
	}
	return &__.UserDetailResp{
		Id:                       u.Id,
		Mobile:                   u.Mobile,
		Password:                 u.Password,
		NickName:                 u.NickName,
		RealName:                 u.RealName,
		IdCard:                   u.IdCard,
		Sex:                      int32(u.Sex),
		Address:                  u.Address,
		Signature:                u.Signature,
		Status:                   int32(u.Status),
		IdCardVerificationStatus: int32(u.IdCardVerificationStatus),
		CreateTime:               u.CreatedAt.Format(time.DateTime),
	}, nil
}

// 兴趣列表
func (s *Server) ListInterests(_ context.Context, _ *__.ListInterestsReq) (*__.ListInterestsResp, error) {
	list, err := dao.ListInterests()
	if err != nil {
		return nil, err
	}
	resp := &__.ListInterestsResp{}
	for _, it := range list {
		resp.Items = append(resp.Items, &__.InterestItem{Id: it.Id, Name: it.Name, Sort: it.Sort})
	}
	return resp, nil
}

// 设置用户兴趣（最多 10 个）
func (s *Server) SetUserInterests(_ context.Context, in *__.SetUserInterestsReq) (*__.SetUserInterestsResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	if err := dao.SetUserInterests(in.UserId, in.InterestIds); err != nil {
		return nil, err
	}
	return &__.SetUserInterestsResp{}, nil
}

// 获取用户兴趣
func (s *Server) GetUserInterests(_ context.Context, in *__.GetUserInterestsReq) (*__.GetUserInterestsResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	list, err := dao.GetUserInterests(in.UserId)
	if err != nil {
		return nil, err
	}
	resp := &__.GetUserInterestsResp{}
	for _, it := range list {
		resp.Items = append(resp.Items, &__.InterestItem{Id: it.Id, Name: it.Name, Sort: it.Sort})
	}
	return resp, nil
}

const (
	maxAttempts = 7
	upperLimit  = 100
)

// 游戏状态
type game struct {
	target   int
	used     int
	isOver   bool
	isWin    bool
	lastHint string
}

// GRPCServer 实现 gRPC 服务接口
type GRPCServer struct {
	games  map[int32]*game // 存储所有游戏，key: game_id
	mu     sync.Mutex
	nextID int32
}

func NewGRPCServer() *GRPCServer {
	rand.Seed(time.Now().UnixNano())
	return &GRPCServer{
		games:  make(map[int32]*game),
		nextID: 1,
	}
}

// 新建游戏
func (s *GRPCServer) NewGame(ctx context.Context, req *__.NewGameRequest) (*__.NewGameResponse, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	gameID := s.nextID
	s.nextID++

	// 生成1~100的随机数
	target := rand.Intn(upperLimit) + 1
	s.games[gameID] = &game{
		target: target,
		used:   0,
		isOver: false,
		isWin:  false,
	}

	return &__.NewGameResponse{
		GameId: gameID,
		State: &__.GameState{
			GameId:    gameID,
			Remaining: maxAttempts,
			IsOver:    false,
			IsWin:     false,
		},
	}, nil
}

// 处理猜测
func (s *GRPCServer) Guess(ctx context.Context, req *__.GuessRequest) (*__.GuessResponse, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	gameID := req.GameId
	g, exists := s.games[gameID]
	if !exists {
		return &__.GuessResponse{
			State: &__.GameState{
				GameId: gameID,
				Hint:   "游戏不存在",
				IsOver: true,
			},
		}, nil
	}

	// 游戏已结束
	if g.isOver {
		return &__.GuessResponse{
			State: &__.GameState{
				GameId:    gameID,
				Remaining: 0,
				IsOver:    true,
				IsWin:     g.isWin,
				Hint:      g.lastHint,
				Target:    int32(g.target),
			},
		}, nil
	}

	// 验证输入范围
	num := req.Number
	if num < 1 || num > upperLimit {
		return &__.GuessResponse{
			State: &__.GameState{
				GameId:    gameID,
				Remaining: int32(maxAttempts - g.used),
				IsOver:    false,
				Hint:      "请输入1~100之间的数字",
			},
		}, nil
	}

	// 处理猜测
	g.used++
	switch {
	case num == int32(g.target):
		g.isWin = true
		g.isOver = true
		g.lastHint = "恭喜你，猜中了！"
	case num < int32(g.target):
		g.lastHint = "小了！"
	default:
		g.lastHint = "大了！"
	}

	// 检查次数是否用完
	if g.used >= maxAttempts && !g.isWin {
		g.isOver = true
		g.lastHint = "次数用完了"
	}

	// 构建响应
	return &__.GuessResponse{
		State: &__.GameState{
			GameId:    gameID,
			Remaining: int32(maxAttempts - g.used),
			IsOver:    g.isOver,
			IsWin:     g.isWin,
			Hint:      g.lastHint,
			Target: func() int32 { // 仅结束时返回答案
				if g.isOver {
					return int32(g.target)
				}
				return 0
			}(),
		},
	}, nil
}

// GetSwipeCandidates 获取滑动候选用户（智能补充）
func (s *Server) GetSwipeCandidates(_ context.Context, in *__.GetSwipeCandidatesReq) (*__.GetSwipeCandidatesResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 设置默认限制数量
	limit := int(in.Limit)
	if limit <= 0 {
		limit = 10
	}

	// 【智能补充机制】先检查候选池数量
	go dao.SmartRefillCandidates(in.UserId) // 异步补充，不阻塞响应

	// 获取候选用户列表
	candidates, err := dao.GetSwipeCandidates(in.UserId, limit)
	if err != nil {
		return nil, err
	}

	// 如果候选用户不足，立即生成（同步）
	if len(candidates) < limit {
		err = dao.GenerateSwipeCandidates(in.UserId, 50) // 一次生成50个
		if err != nil {
			// 生成失败不影响返回现有结果
		}
		// 重新获取候选用户
		candidates, err = dao.GetSwipeCandidates(in.UserId, limit)
		if err != nil {
			return nil, err
		}
	}

	resp := &__.GetSwipeCandidatesResp{}
	for _, candidate := range candidates {
		// 获取候选用户详细信息
		user, err := dao.GetUserById(candidate.CandidateId)
		if err != nil {
			continue // 跳过获取失败的用户
		}

		// 获取候选用户的兴趣标签
		interests, err := dao.GetUserInterests(candidate.CandidateId)
		if err != nil {
			interests = []models.Interest{} // 如果获取失败，使用空列表
		}

		// 构建兴趣标签列表
		var interestItems []*__.InterestItem
		for _, interest := range interests {
			interestItems = append(interestItems, &__.InterestItem{
				Id:   interest.Id,
				Name: interest.Name,
				Sort: interest.Sort,
			})
		}

		// 添加到响应中
		resp.Candidates = append(resp.Candidates, &__.SwipeCandidateItem{
			Id:         user.Id,
			NickName:   user.NickName,
			Sex:        int32(user.Sex),
			Signature:  user.Signature,
			Avatar:     "", // 这里可以添加头像字段
			Age:        0,  // 这里可以添加年龄计算逻辑
			Address:    user.Address,
			MatchScore: candidate.MatchScore,
			Reason:     candidate.Reason,
			Interests:  interestItems,
		})
	}

	return resp, nil
}

// SwipeAction 执行滑动动作
func (s *Server) SwipeAction(_ context.Context, in *__.SwipeActionReq) (*__.SwipeActionResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	if in.TargetId == 0 {
		return nil, errors.New("目标用户ID不能为空")
	}
	if in.Action != 1 && in.Action != 2 {
		return nil, errors.New("滑动动作无效，1-左滑无感 2-右滑喜欢")
	}

	// 检查是否已经滑动过该用户
	hasSwiped, err := dao.CheckSwipeRecord(in.UserId, in.TargetId)
	if err != nil {
		return nil, err
	}
	if hasSwiped {
		return nil, errors.New("已经滑动过该用户")
	}

	// 获取目标用户信息用于计算匹配分数
	targetUser, err := dao.GetUserById(in.TargetId)
	if err != nil {
		return nil, errors.New("目标用户不存在")
	}

	// 获取当前用户信息
	currentUser, err := dao.GetUserById(in.UserId)
	if err != nil {
		return nil, errors.New("当前用户不存在")
	}

	// 获取当前用户兴趣用于计算匹配分数
	currentUserInterests, err := dao.GetUserInterests(in.UserId)
	if err != nil {
		currentUserInterests = []models.Interest{}
	}

	// 计算匹配分数
	matchScore := calculateMatchScore(currentUser, targetUser, currentUserInterests)

	// 创建滑动记录
	err = dao.CreateSwipeRecord(in.UserId, in.TargetId, int8(in.Action), matchScore)
	if err != nil {
		return nil, err
	}

	resp := &__.SwipeActionResp{
		IsMatch: false,
		Message: "滑动成功",
	}

	// 如果是右滑喜欢，检查是否匹配
	if in.Action == 2 {
		// 检查目标用户是否也右滑了当前用户
		hasTargetSwiped, err := dao.CheckSwipeRecord(in.TargetId, in.UserId)
		if err != nil {
			return nil, err
		}

		if hasTargetSwiped {
			// 检查目标用户的滑动动作
			var targetSwipeRecord models.SwipeRecord
			targetSwipeRecord.UserId = in.TargetId
			targetSwipeRecord.TargetId = in.UserId
			err = targetSwipeRecord.GetByUserAndTarget()
			if err == nil && targetSwipeRecord.Action == 2 {
				// 双方都喜欢，创建匹配记录
				matchId, err := dao.CreateMatchRecord(in.UserId, in.TargetId, matchScore)
				if err != nil {
					return nil, err
				}

				resp.IsMatch = true
				resp.MatchId = matchId
				resp.Message = "匹配成功！"
			}
		}
	}

	return resp, nil
}

// GetMatchList 获取匹配列表
func (s *Server) GetMatchList(_ context.Context, in *__.GetMatchListReq) (*__.GetMatchListResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 设置默认分页参数
	page := int(in.Page)
	pageSize := int(in.PageSize)
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 20
	}

	// 获取匹配列表
	matches, total, err := dao.GetMatchList(in.UserId, page, pageSize)
	if err != nil {
		return nil, err
	}

	resp := &__.GetMatchListResp{
		Total:    int32(total),
		Page:     int32(page),
		PageSize: int32(pageSize),
	}

	for _, match := range matches {
		// 确定对方用户ID
		var otherUserId uint64
		if match.User1Id == in.UserId {
			otherUserId = match.User2Id
		} else {
			otherUserId = match.User1Id
		}

		// 获取对方用户信息
		otherUser, err := dao.GetUserById(otherUserId)
		if err != nil {
			continue // 跳过获取失败的用户
		}

		// 添加到响应中
		resp.Matches = append(resp.Matches, &__.MatchItem{
			MatchId:      match.Id,
			UserId:       otherUser.Id,
			NickName:     otherUser.NickName,
			Avatar:       "", // 这里可以添加头像字段
			Signature:    otherUser.Signature,
			MatchTime:    match.CreatedAt.Format(time.DateTime),
			MatchScore:   match.MatchScore,
			FirstMessage: match.FirstMessage,
		})
	}

	return resp, nil
}

// Unmatch 解除匹配
func (s *Server) Unmatch(_ context.Context, in *__.UnmatchReq) (*__.UnmatchResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	if in.MatchId == 0 {
		return nil, errors.New("匹配记录ID不能为空")
	}

	err := dao.UnmatchUser(in.UserId, in.MatchId)
	if err != nil {
		return &__.UnmatchResp{
			Success: false,
			Message: err.Error(),
		}, nil
	}

	return &__.UnmatchResp{
		Success: true,
		Message: "解除匹配成功",
	}, nil
}

// calculateMatchScore 计算匹配分数（与DAO层保持一致）
func calculateMatchScore(user, candidate models.User, userInterests []models.Interest) float64 {
	score := 0.0

	// 基础分数
	score += 0.3

	// 兴趣匹配
	if len(userInterests) > 0 {
		candidateInterests, err := dao.GetUserInterests(candidate.Id)
		if err == nil {
			// 计算兴趣重叠度
			commonInterests := 0
			for _, userInterest := range userInterests {
				for _, candidateInterest := range candidateInterests {
					if userInterest.Id == candidateInterest.Id {
						commonInterests++
						break
					}
				}
			}
			// 兴趣匹配分数
			score += float64(commonInterests) / float64(len(userInterests)) * 0.5
		}
	}

	// 在线状态奖励
	if candidate.Status == 1 {
		score += 0.1
	}

	// 实名认证奖励
	if candidate.IdCardVerificationStatus == 2 {
		score += 0.1
	}

	// 确保分数在0-1之间
	if score > 1.0 {
		score = 1.0
	}

	return score
}

// SendChatMessage 发送聊天消息
func (s *Server) SendChatMessage(_ context.Context, in *__.SendChatMessageReq) (*__.SendChatMessageResp, error) {
	if in.MatchId == 0 {
		return nil, errors.New("匹配ID不能为空")
	}
	if in.SenderId == 0 {
		return nil, errors.New("发送者ID不能为空")
	}
	if in.ReceiverId == 0 {
		return nil, errors.New("接收者ID不能为空")
	}
	if in.Content == "" {
		return nil, errors.New("消息内容不能为空")
	}

	// 设置默认消息类型
	messageType := int8(in.MessageType)
	if messageType == 0 {
		messageType = 1 // 默认文本消息
	}

	// 发送消息并保存到数据库
	message, err := dao.SendChatMessage(
		in.MatchId,
		in.SenderId,
		in.ReceiverId,
		in.Content,
		messageType,
	)
	if err != nil {
		return nil, err
	}

	return &__.SendChatMessageResp{
		MessageId:  message.Id,
		CreateTime: message.CreatedAt.Format(time.DateTime),
	}, nil
}

// GetChatHistory 获取聊天历史
func (s *Server) GetChatHistory(_ context.Context, in *__.GetChatHistoryReq) (*__.GetChatHistoryResp, error) {
	if in.MatchId == 0 {
		return nil, errors.New("匹配ID不能为空")
	}
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 设置默认分页参数
	page := int(in.Page)
	pageSize := int(in.PageSize)
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 20
	}

	// 获取聊天历史
	messages, total, err := dao.GetChatHistory(in.MatchId, in.UserId, page, pageSize)
	if err != nil {
		return nil, err
	}

	resp := &__.GetChatHistoryResp{
		Total:    int32(total),
		Page:     int32(page),
		PageSize: int32(pageSize),
	}

	for _, msg := range messages {
		resp.Messages = append(resp.Messages, &__.ChatMessageItem{
			MessageId:   msg.Id,
			SenderId:    msg.SenderId,
			ReceiverId:  msg.ReceiverId,
			Content:     msg.Content,
			MessageType: int32(msg.MessageType),
			IsRead:      msg.IsRead == 1,
			CreateTime:  msg.CreatedAt.Format(time.DateTime),
		})
	}

	return resp, nil
}

// MarkChatAsRead 标记聊天消息为已读
func (s *Server) MarkChatAsRead(_ context.Context, in *__.MarkChatAsReadReq) (*__.MarkChatAsReadResp, error) {
	if in.MatchId == 0 {
		return nil, errors.New("匹配ID不能为空")
	}
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	err := dao.MarkChatAsRead(in.MatchId, in.UserId)
	if err != nil {
		return &__.MarkChatAsReadResp{
			Success: false,
			Message: err.Error(),
		}, nil
	}

	return &__.MarkChatAsReadResp{
		Success: true,
		Message: "标记已读成功",
	}, nil
}

// GetUnreadCount 获取未读消息统计
func (s *Server) GetUnreadCount(_ context.Context, in *__.GetUnreadCountReq) (*__.GetUnreadCountResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	unreadMap, err := dao.GetUnreadChatCount(in.UserId)
	if err != nil {
		return nil, err
	}

	resp := &__.GetUnreadCountResp{}
	for matchId, count := range unreadMap {
		resp.Items = append(resp.Items, &__.UnreadCountItem{
			MatchId: matchId,
			Count:   count,
		})
	}

	return resp, nil
}

// GetNearbyUsers 获取附近的用户
func (s *Server) GetNearbyUsers(_ context.Context, in *__.GetNearbyUsersReq) (*__.GetNearbyUsersResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 设置默认值
	radius := in.Radius
	if radius <= 0 {
		radius = 10 // 默认10km
	}
	if radius > 50 {
		radius = 50 // 最大50km
	}

	limit := int(in.Limit)
	if limit <= 0 {
		limit = 20
	}

	// 获取附近的用户
	nearbyUsers, err := dao.GetNearbyUsers(in.UserId, radius, limit)
	if err != nil {
		return nil, err
	}

	// 获取当前用户信息（用于计算距离）
	var currentUser models.User
	currentUser.Id = in.UserId
	err = currentUser.GetById()
	if err != nil {
		return nil, errors.New("获取用户信息失败：" + err.Error())
	}

	resp := &__.GetNearbyUsersResp{}

	for _, user := range nearbyUsers {
		// 计算距离
		var distance float64
		if currentUser.Latitude != nil && currentUser.Longitude != nil &&
			user.Latitude != nil && user.Longitude != nil {
			distance = untils.CalculateDistance(
				*currentUser.Latitude, *currentUser.Longitude,
				*user.Latitude, *user.Longitude,
			)
		}

		// 获取用户的兴趣标签
		interests, err := dao.GetUserInterests(user.Id)
		if err != nil {
			interests = []models.Interest{}
		}

		// 构建兴趣标签列表
		var interestItems []*__.InterestItem
		for _, interest := range interests {
			interestItems = append(interestItems, &__.InterestItem{
				Id:   interest.Id,
				Name: interest.Name,
				Sort: interest.Sort,
			})
		}

		// 添加到响应中
		resp.Users = append(resp.Users, &__.NearbyUserItem{
			Id:           user.Id,
			NickName:     user.NickName,
			Sex:          int32(user.Sex),
			Age:          0,  // 这里可以根据生日计算年龄
			Avatar:       "", // 这里可以添加头像字段
			Signature:    user.Signature,
			Address:      user.Address,
			Distance:     distance,
			DistanceText: untils.FormatDistance(distance),
			Interests:    interestItems,
		})
	}

	return resp, nil
}

// ==================== 灵魂匹配相关接口 ====================

// GetSoulQuestions 获取灵魂测试题目
// 根据分类ID获取题目列表，支持随机获取和按分类获取
func (s *Server) GetSoulQuestions(_ context.Context, in *__.GetSoulQuestionsReq) (*__.GetSoulQuestionsResp, error) {
	// 设置默认限制数量
	limit := int(in.Limit)
	if limit <= 0 {
		limit = 20
	}

	// 获取题目
	var questions []models.SoulQuestion
	var err error

	if in.CategoryId == 0 {
		// 获取所有分类的随机题目
		questions, err = (&dao.SoulQuestionDAO{}).GetRandomQuestions(limit)
	} else {
		// 获取指定分类的题目
		questions, err = (&dao.SoulQuestionDAO{}).GetQuestionsByCategory(in.CategoryId, limit)
	}

	if err != nil {
		return nil, err
	}

	// 构建响应数据
	resp := &__.GetSoulQuestionsResp{}
	for _, question := range questions {
		resp.Questions = append(resp.Questions, &__.SoulQuestionItem{
			Id:           question.Id,
			CategoryId:   question.CategoryId,
			QuestionText: question.QuestionText,
			QuestionType: int32(question.QuestionType),
			Options:      question.Options,
			Weight:       question.Weight,
			Difficulty:   int32(question.Difficulty),
		})
	}

	return resp, nil
}

// GetSoulQuestionCategories 获取题目分类
// 返回所有启用的题目分类列表
func (s *Server) GetSoulQuestionCategories(_ context.Context, in *__.GetSoulQuestionCategoriesReq) (*__.GetSoulQuestionCategoriesResp, error) {
	var category models.SoulQuestionCategory
	categories, err := category.GetAll()
	if err != nil {
		return nil, err
	}

	resp := &__.GetSoulQuestionCategoriesResp{}
	for _, cat := range categories {
		resp.Categories = append(resp.Categories, &__.SoulQuestionCategoryItem{
			Id:          cat.Id,
			Name:        cat.Name,
			Description: cat.Description,
			Weight:      cat.Weight,
		})
	}

	return resp, nil
}

// SubmitSoulAnswer 提交灵魂测试答案
// 保存用户对单个题目的答案和分数
func (s *Server) SubmitSoulAnswer(_ context.Context, in *__.SubmitSoulAnswerReq) (*__.SubmitSoulAnswerResp, error) {
	// 参数验证
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	if in.QuestionId == 0 {
		return nil, errors.New("题目ID不能为空")
	}
	if in.AnswerContent == "" {
		return nil, errors.New("答案内容不能为空")
	}

	// 保存答案到数据库
	err := (&dao.SoulAnswerDAO{}).SaveAnswer(
		in.UserId,
		in.QuestionId,
		in.AnswerContent,
		in.AnswerScore,
	)

	if err != nil {
		return &__.SubmitSoulAnswerResp{
			Success: false,
			Message: "保存答案失败：" + err.Error(),
		}, nil
	}

	return &__.SubmitSoulAnswerResp{
		Success: true,
		Message: "答案提交成功",
	}, nil
}

// CompleteSoulTest 完成测试
func (s *Server) CompleteSoulTest(_ context.Context, in *__.CompleteSoulTestReq) (*__.CompleteSoulTestResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	if in.TestVersion == "" {
		return nil, errors.New("测试版本不能为空")
	}

	// 获取用户所有答案
	answers, err := (&dao.SoulAnswerDAO{}).GetUserAnswers(in.UserId)
	if err != nil {
		return nil, errors.New("获取用户答案失败：" + err.Error())
	}

	if len(answers) == 0 {
		return nil, errors.New("用户未完成任何题目")
	}

	// 计算测试结果
	totalScore, dimensionScores, personalityType, matchPreferences, err := s.calculateSoulTestResult(in.UserId, answers)
	if err != nil {
		return nil, errors.New("计算测试结果失败：" + err.Error())
	}

	// 保存测试结果
	err = (&dao.SoulTestResultDAO{}).SaveTestResult(
		in.UserId,
		in.TestVersion,
		totalScore,
		dimensionScores,
		personalityType,
		matchPreferences,
		int(in.TestDuration),
	)

	if err != nil {
		return nil, errors.New("保存测试结果失败：" + err.Error())
	}

	// 保存用户维度分数
	err = (&dao.SoulUserDimensionScoreDAO{}).SaveUserDimensionScores(in.UserId, parseDimensionScores(dimensionScores))
	if err != nil {
		// 维度分数保存失败不影响主流程
		// 保存用户维度分数失败，记录错误但不影响主流程
		// fmt.Printf("保存用户维度分数失败: %v\n", err)
	}

	return &__.CompleteSoulTestResp{
		Success:         true,
		Message:         "测试完成成功",
		TotalScore:      totalScore,
		PersonalityType: personalityType,
		MatchReasons:    generateMatchReasons(totalScore),
	}, nil
}

// GetSoulTestResult 获取测试结果
func (s *Server) GetSoulTestResult(_ context.Context, in *__.GetSoulTestResultReq) (*__.GetSoulTestResultResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	result, err := (&dao.SoulTestResultDAO{}).GetUserTestResult(in.UserId)
	if err != nil {
		return &__.GetSoulTestResultResp{
			HasResult: false,
		}, nil
	}

	// 检查结果是否为空
	if result == nil {
		return &__.GetSoulTestResultResp{
			HasResult: false,
		}, nil
	}

	return &__.GetSoulTestResultResp{
		HasResult:        true,
		TotalScore:       result.TotalScore,
		DimensionScores:  result.DimensionScores,
		PersonalityType:  result.PersonalityType,
		MatchPreferences: result.MatchPreferences,
		CompletedAt:      result.CompletedAt.Format(time.DateTime),
	}, nil
}

// GetSoulMatchCandidates 获取灵魂匹配候选用户
func (s *Server) GetSoulMatchCandidates(_ context.Context, in *__.GetSoulMatchCandidatesReq) (*__.GetSoulMatchCandidatesResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	limit := int(in.Limit)
	if limit <= 0 {
		limit = 10
	}

	// 获取候选用户
	candidates, err := (&dao.SoulMatchDAO{}).GetSoulMatchCandidates(in.UserId, limit)
	if err != nil {
		return nil, err
	}

	resp := &__.GetSoulMatchCandidatesResp{}
	for _, candidate := range candidates {
		// 计算匹配分数
		matchScore, matchReasons, err := (&dao.SoulMatchDAO{}).CalculateSoulMatchScore(in.UserId, candidate.Id)
		if err != nil {
			continue
		}

		// 获取候选用户的测试结果
		candidateResult, err := (&dao.SoulTestResultDAO{}).GetUserTestResult(candidate.Id)
		if err != nil {
			continue
		}

		// 获取候选用户的兴趣标签
		interests, err := dao.GetUserInterests(candidate.Id)
		if err != nil {
			interests = []models.Interest{}
		}

		// 构建兴趣标签列表
		var interestItems []*__.InterestItem
		for _, interest := range interests {
			interestItems = append(interestItems, &__.InterestItem{
				Id:   interest.Id,
				Name: interest.Name,
				Sort: interest.Sort,
			})
		}

		resp.Candidates = append(resp.Candidates, &__.SoulMatchCandidateItem{
			Id:              candidate.Id,
			NickName:        candidate.NickName,
			Sex:             int32(candidate.Sex),
			Age:             0,  // 可以根据生日计算
			Avatar:          "", // 可以添加头像字段
			Signature:       candidate.Signature,
			Address:         candidate.Address,
			MatchScore:      matchScore,
			MatchReasons:    matchReasons,
			PersonalityType: candidateResult.PersonalityType,
			Interests:       interestItems,
		})
	}

	return resp, nil
}

// GetSoulMatches 获取灵魂匹配列表
func (s *Server) GetSoulMatches(_ context.Context, in *__.GetSoulMatchesReq) (*__.GetSoulMatchesResp, error) {
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	limit := int(in.Limit)
	if limit <= 0 {
		limit = 20
	}

	// 获取匹配记录
	records, err := (&dao.SoulMatchDAO{}).GetSoulMatches(in.UserId, limit)
	if err != nil {
		return nil, err
	}

	resp := &__.GetSoulMatchesResp{}
	for _, record := range records {
		// 确定匹配的用户ID
		var matchedUserId uint64
		if record.User1Id == in.UserId {
			matchedUserId = record.User2Id
		} else {
			matchedUserId = record.User1Id
		}

		// 获取匹配用户信息
		var matchedUser models.User
		matchedUser.Id = matchedUserId
		err = matchedUser.GetById()
		if err != nil {
			continue
		}

		// 获取匹配用户的测试结果
		matchedResult, err := (&dao.SoulTestResultDAO{}).GetUserTestResult(matchedUserId)
		if err != nil {
			continue
		}

		resp.Matches = append(resp.Matches, &__.SoulMatchItem{
			UserId:          matchedUserId,
			NickName:        matchedUser.NickName,
			Avatar:          "", // 可以添加头像字段
			MatchScore:      record.MatchScore,
			MatchReasons:    record.MatchReasons,
			PersonalityType: matchedResult.PersonalityType,
			MatchedAt:       record.CreatedAt.Format(time.DateTime),
		})
	}

	return resp, nil
}

// ==================== 辅助函数 ====================

// calculateSoulTestResult 计算灵魂测试结果
func (s *Server) calculateSoulTestResult(userId uint64, answers []models.SoulAnswer) (float64, string, string, string, error) {
	// 获取所有维度
	dimensions, err := (&dao.SoulPersonalityDimensionDAO{}).GetAllDimensions()
	if err != nil {
		return 0, "", "", "", err
	}

	// 初始化维度分数
	dimensionScores := make(map[string]float64)
	for _, dimension := range dimensions {
		dimensionScores[dimension.DimensionCode] = 0.0
	}

	// 计算各维度分数
	totalScore := 0.0
	totalWeight := 0.0

	for _, answer := range answers {
		// 获取题目信息
		question, err := (&dao.SoulQuestionDAO{}).GetQuestionById(answer.QuestionId)
		if err != nil {
			continue
		}

		// 根据题目类型和答案计算分数
		score := answer.AnswerScore * question.Weight
		totalScore += score
		totalWeight += question.Weight

		// 这里可以根据题目的分类或标签来分配到不同维度
		// 简化处理：根据题目ID的奇偶性分配到不同维度
		if len(dimensions) > 0 {
			dimensionIndex := int(answer.QuestionId) % len(dimensions)
			dimensionCode := dimensions[dimensionIndex].DimensionCode
			dimensionScores[dimensionCode] += score
		}
	}

	// 计算平均分数
	if totalWeight > 0 {
		totalScore = totalScore / totalWeight * 100
	}

	// 序列化维度分数
	dimensionScoresJson, _ := json.Marshal(dimensionScores)

	// 确定性格类型
	personalityType := determinePersonalityType(dimensionScores)

	// 生成匹配偏好
	matchPreferences := generateMatchPreferences(dimensionScores)

	return totalScore, string(dimensionScoresJson), personalityType, matchPreferences, nil
}

// determinePersonalityType 确定性格类型
func determinePersonalityType(dimensionScores map[string]float64) string {
	// 简化的性格类型判断逻辑
	// 实际应用中可以使用更复杂的算法
	maxScore := 0.0
	personalityType := "平衡型"

	for code, score := range dimensionScores {
		if score > maxScore {
			maxScore = score
			switch code {
			case "EXTROVERSION":
				personalityType = "外向型"
			case "INTROVERSION":
				personalityType = "内向型"
			case "SENSING":
				personalityType = "感觉型"
			case "INTUITION":
				personalityType = "直觉型"
			case "THINKING":
				personalityType = "思考型"
			case "FEELING":
				personalityType = "情感型"
			case "JUDGING":
				personalityType = "判断型"
			case "PERCEIVING":
				personalityType = "感知型"
			default:
				personalityType = "平衡型"
			}
		}
	}

	return personalityType
}

// generateMatchPreferences 生成匹配偏好
func generateMatchPreferences(dimensionScores map[string]float64) string {
	preferences := make(map[string]interface{})

	// 根据维度分数生成偏好
	for code, score := range dimensionScores {
		if score > 70 {
			preferences[code+"_preference"] = "high"
		} else if score > 40 {
			preferences[code+"_preference"] = "medium"
		} else {
			preferences[code+"_preference"] = "low"
		}
	}

	preferencesJson, _ := json.Marshal(preferences)
	return string(preferencesJson)
}

// generateMatchReasons 生成匹配原因
func generateMatchReasons(totalScore float64) string {
	var reasons []string

	if totalScore > 80 {
		reasons = append(reasons, "高度契合的灵魂伴侣")
	} else if totalScore > 60 {
		reasons = append(reasons, "较为契合的匹配对象")
	} else if totalScore > 40 {
		reasons = append(reasons, "有一定契合度的用户")
	} else {
		reasons = append(reasons, "基础匹配用户")
	}

	reasonsJson, _ := json.Marshal(reasons)
	return string(reasonsJson)
}

// parseDimensionScores 解析维度分数
func parseDimensionScores(dimensionScoresJson string) map[string]float64 {
	var scores map[string]float64
	json.Unmarshal([]byte(dimensionScoresJson), &scores)
	return scores
}
